package com.glsc.ngateway.opmanage.utils;


import cn.hutool.core.util.StrUtil;
import com.glsc.ngateway.opmanage.aspect.JwtHelper;
import com.glsc.ngateway.opmanage.aspect.UserCache;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.User;
import com.glsc.ngateway.opmanage.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;

/**
 * @author zhouzp
 * @date 2020/6/1
 * 解析请求上线文的用户信息，主要通过token获取当前操作用户信息
 */
@Component("requestTool")
public class RequestTool {
    private static Logger logger = LoggerFactory.getLogger(RequestTool.class);

    @Resource
    private UserCache userCache;

    @Resource
    private UserService userService;
//
//    @Resource(name = "userService")
//    public void setUserService(UserService userService) {
//        RequestTool.userService = userService;
//    }
//
    /**
     * 根据当前登录获取token对应的登录用户
     */
    public String getAccountFromRequest(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (null == token) {
            return null;
        }

        try {
            //1.尝试sso token解析
            String ssoTokenAccount = userService.getAccountByGatewaySSOToken(token);
            if(StrUtil.isNotEmpty(ssoTokenAccount)){
                return ssoTokenAccount;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("sso解析token失败"+e);
        }

        //2.尝试本地token解析
        String account = JwtHelper.parseToken(token);
        return account;
    }
//
//    /**
//     * 该方法主要是service层使用，避免通过Controller传递request参数给service层使用
//     * 当service层需要保存当前操作用户等信息时可以直接获取
//     */
//    public static String getAccountFromRequest() {
//        String operatorAccountFromToken = "";
//        try {
//            RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
//            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
//            operatorAccountFromToken = getAccountFromRequest(request);
//        } catch (Exception e) {
//            logger.debug("获取当前系统操作关联用户失败，", e);
//        }
//        if (StrUtil.isEmpty(operatorAccountFromToken)) {
//            logger.debug("获取当前系统操作关联用户失败，未能解析出操作用户账户");
//        }
//        return operatorAccountFromToken;
//    }
//
//    /**
//     * 获取当前操作用户User信息
//     * 该方法主要是service层使用，避免通过Controller传递request参数给service层使用
//     * 当service层需要保存当前操作用户等信息时可以直接获取
//     */
    public User getUserFromRequest(HttpServletRequest request) {
        String opAccount = this.getAccountFromRequest(request);
        if (StrUtil.isEmpty(opAccount)) {
            return null;
        }
        User opUser = userCache.get(opAccount);
        return opUser;
    }

    /**
     * 获取当前操作用户User信息
     * 该方法主要是service层使用，避免通过Controller传递request参数给service层使用
     * 当service层需要保存当前操作用户等信息时可以直接获取
     */
    public  User getUserFromRequest() {
        String opAccount = getAccountFromRequest();
        if (StrUtil.isEmpty(opAccount)) {
            return null;
        }
        User opUser = userCache.get(opAccount);
        return opUser;
    }

    /**
     * 该方法主要是service层使用，避免通过Controller传递request参数给service层使用
     * 当service层需要保存当前操作用户等信息时可以直接获取
     */
    public String getAccountFromRequest() {
        String operatorAccountFromToken = "";
        try {
            RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            operatorAccountFromToken = this.getAccountFromRequest(request);
        } catch (Exception e) {
            logger.debug("获取当前系统操作关联用户失败，", e);
        }
        if (StrUtil.isEmpty(operatorAccountFromToken)) {
            logger.debug("获取当前系统操作关联用户失败，未能解析出操作用户账户");
        }
        return operatorAccountFromToken;
    }
//
//    /**
//     * 通过反射，向domain对象填充操作人员信息，支持两级继承
//     *
//     * @return
//     */
//    public static Object fillOpInfo(Object obj) {
//        return RequestTool.fillOpInfo(obj, null, null,null);
//    }
//
//    /**
//     * 通过反射，向domain对象填充操作人员信息，支持两级继承
//     * 解决列表循环反复调用用户，提供先查询用户，再反射信息的方法
//     *
//     * @param user 操作用户
//     * @return
//     */
//    public static Object fillOpInfo(Object obj, User user) {
//        return RequestTool.fillOpInfo(obj, null, null, user);
//    }
//
//    /**
//     * 通过反射，向domain对象填充操作人员信息，支持两级继承
//     *
//     * @return
//     */
//    public static Object fillOpInfo(Object obj, String opSource, String opAction) {
//        return RequestTool.fillOpInfo(obj, opSource, opAction, null);
//    }
//
//    /**
//     * 通过反射，向domain对象填充操作人员信息，支持两级继承
//     *
//     * @return
//     */
//    public static Object fillOpInfo(Object obj, String opSource, String opAction,User user) {
//        String operator = null;
//        if (user == null) {
//            operator = RequestTool.getAccountFromRequest();
//            if(StrUtil.isNotEmpty(operator)) {
//                user = CacheManager.getUserFromDB(operator);
//            }
//        } else {
//            operator = user.getAccount();
//        }
//        if (user == null || StrUtil.isEmpty(user.getName())) {
//            return obj;
//        }
//
//        HashMap<String, String> opInfoMap = new HashMap<>();
//        opInfoMap.put("opSource", opSource);
//        opInfoMap.put("opAction", opAction);
//        opInfoMap.put("opOperator", operator);
//        opInfoMap.put("operator", operator);
//        opInfoMap.put("opOperatorName", user.getName());
//        opInfoMap.put("operatorName", user.getName());
//
//        // 获取obj类的字节文件对象
//        Class clazz = obj.getClass();
//        Type superClazz = clazz.getGenericSuperclass();
//        Field field =null;//先从当前类找属性，没有则查找父类
//        Method method=null;//父类的setter方法
//        for (String filedStr : opInfoMap.keySet()) {
//            if (opInfoMap.get(filedStr) == null) {
//                continue;
//            }
//            try {
//                field = clazz.getDeclaredField(filedStr); // 获取该类的成员变量
//                field.setAccessible(true);  // 取消语言访问检查
//                field.set(obj, opInfoMap.get(filedStr));  // 给变量赋值
//            } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
////                logger.warn("对象"+obj.getClass()+"，设置属性"+filedStr+"异常",e);
//            } catch (NoSuchFieldException e) {
//                try {
////                    logger.warn(clazz.toString()+"没有找到属性+"+filedStr+"，尝试父类查找set方法.");
//                    //尝试使用父类的方法
//                    if (null != superClazz) {
//                        method = ((Class) superClazz).getMethod("set"+CommonUtils.upperFirstChar(filedStr),String.class);
//                        method.setAccessible(true);  // 取消语言访问检查
//                        method.invoke(obj,opInfoMap.get(filedStr));
//
////                        logger.warn(clazz.toString()+"没有找到属性+"+filedStr+"，尝试父类查找set方法成功===");
//                    }
//                } catch (SecurityException | IllegalArgumentException | IllegalAccessException e2) {
////                    logger.warn("对象"+obj.getClass()+"，设置属性"+filedStr+"，查找父类方法异常");
//                } catch (Exception e2) {
////                    logger.warn("对象"+obj.getClass()+"，设置属性"+filedStr+"，查找父类方法异常");
//                }
//
//            }
//        }
//
//        return obj;
//    }

    //获取本机IP地址
    public static String getLocalHost() {
        String hostInfo=null;
        try {
            InetAddress addr = InetAddress.getLocalHost();
            String ip = addr.getHostAddress().toString();//获得本机IP
            String host = addr.getHostName().toString();//获得本机名称
            hostInfo="ip="+ip+","+"host="+host;
        } catch (Exception e) {
            hostInfo="获取本机host信息异常";
        }
        return hostInfo;
    }

    //获取本机IP地址
    public static String getLocalIP() {
        try {
            InetAddress addr = InetAddress.getLocalHost();
            String ip = addr.getHostAddress().toString();//获得本机IP
            return ip;
        } catch (Exception e) {
            return "";
        }
    }
}
